#!/usr/bin/env python
#-*-encoding:utf-8-*-
'''
Created on 2014年9月15日

@author: chenyongbing
'''
import re,sys,datetime,os
import tarfile
import logging

from localConfig import LocalConfig
myLocalConfig = LocalConfig()
class IdentifyRole(object):
    '''
    classdocs
    '''


    def __init__(self,rawfile='',show='all',order='mac',type='detail',efile='',opening='00:00:00.24:00:00',task_name='task_testing',nosysemployee=False):
        '''
        Constructor
        '''
        self.rawfile = rawfile
        self.show = show
        self.order = order
        self.type = type
        self.opening = opening
        self.nosysemployee = nosysemployee
        #logging.basicConfig()
  
        if task_name==None:
            self.task_name = datetime.date.today().strftime('%Y-%m-%d')
        else:
            self.task_name = task_name
    
        self.employee_path = myLocalConfig.employee_path
        #self.EMPLOYEES = self.getEmployee(efile)
        #print self.EMPLOYEES
    def get_dur(self,t1,t2):
        tlist1 = t1.split(':')
        tlist2 = t2.split(':')
        t1_sec = int(tlist1[0]) *3600 + int(tlist1[1]) *60 + int(tlist1[2]) 
        t2_sec = int(tlist2[0]) *3600 + int(tlist2[1]) *60 + int(tlist2[2])  
        dur = t2_sec - t1_sec
        return dur
    
    
    def getEmployeeFromSQL(self,spath,day):
        #EMPLOYEES = {}
        EMPLOYEES = {}
        nday = (datetime.date(int(day[:4]),int(day[5:7]),int(day[8:10])) + datetime.timedelta(1)).strftime('%Y-%m-%d')
        i=0
        #print nday
        
        sfile = spath+'/mac_employee.%s.sql'%nday
        out = open(sfile).read()
        for estrs in re.findall("\([\d]+,([\d]+),'([^\']+)',[\d]+,'[^\']+',([^\,]+),[^\,\)]+\)",out):
            group,mac,day = estrs
            i+=1
            #print i,group,mac,day 
            #if mac not in EMPLOYEES:EMPLOYEES.append(mac)
            if group not in EMPLOYEES.keys():
                EMPLOYEES[group] = []
            EMPLOYEES[group] = EMPLOYEES[group]+[mac]
            #EMPLOYEES[group] =  []
        #print EMPLOYEES
        return EMPLOYEES
    
    def getEmployee(self,efile):
        EMPLOYEES = {}
        out = open(efile).read()
        
        for line in out.split('\n'):
            #print line
            lineList = line.split('\t')
            #print lineList
            if len(lineList)!=2:continue
            group,mac = lineList
            
            if group not in EMPLOYEES.keys():
                EMPLOYEES[group] = []
            EMPLOYEES[group] = EMPLOYEES[group]+[mac]
        return EMPLOYEES
    
    def openTarFile(self,rawfile_tar):
        output = ''
        if not os.path.exists(rawfile_tar):
            return output
        try:
            tar = tarfile.open(rawfile_tar)
        except:
            return output
        for member in tar.getmembers():
            f = tar.extractfile(member)
            out = f.read()
            output = output + out+'\n'
        tar.close()
        return output
    
    
    def openDevTarFile(self,devTarPath='',devices=[]):
        output = ''
        for devices in devices:
            devTarFile = devTarPath+'/'+device+'.txt.tar.gz'
            if not os.path.exists(devTarFile):
                continue
            out = self.openTarFile(devTarFile)
            output+='%s\n'%out
        return output
    
    
    def identify_role_by_dur_with_walkby_list(self,macsDict,maxInterval=30*60,walkbyList=[2*60],rssiList=[-90,-88]):
        datas = {}
        for min_rssi in rssiList:
            datas[min_rssi] = {}
            visitTimeMacs = {}
            for mac,visitMsgs in macsDict.iteritems():
                visitTimeList = []
                for rssi,vtlist in visitMsgs.iteritems():
                    if rssi < min_rssi:continue
                    visitTimeList += vtlist.keys()
                if len(visitTimeList)==0:continue
                visitTimeList.sort()
                visitTimeMacs[mac] = visitTimeList
            for walkby in walkbyList:
                walkby = int(walkby)
                hourMsgs = {}
                for mac , visitTimeList in visitTimeMacs.items():
                    visittimes = len(visitTimeList)
                    st = visitTimeList[0]
                    for i in range(visittimes):
                        t1 = visitTimeList[i]
                        if visittimes==1:
                            t2 = visitTimeList[i]
                        elif i+1>=visittimes:
                            t2 = t1
                        else:
                            t2 = visitTimeList[i+1]
                        if visittimes!=1 and i+1<visittimes and t1==t2 :continue
                        dur = self.get_dur(t1, t2)
                        if dur>maxInterval or dur==0:
                            et = t1
                            cdur = self.get_dur(st, et)
                            if cdur>=walkby:
                                role=3
                            else:role=1
                            
                            hour = st.split(':')[0]
                            if hour not in hourMsgs.keys():
                                hourMsgs[hour] = []
                            hourMsgs[hour]  = hourMsgs[hour] +[{'mac':mac,'role':role,'st':st,'et':et,'dur':cdur}]
                datas[min_rssi][walkby] = hourMsgs
        return datas
    
    def identify_role_by_dur(self,macsDict,maxInterval=30*60,walkby=2*60,max_rssi=0,min_rssi=-90):
        hourMsgs = {}
        macMsgs = {}
       
        for mac,visitMsgs in macsDict.iteritems():
            visitTimeList = []
            for rssi,vtlist in visitMsgs.iteritems():
                #if rssi not in range(min_rssi,max_rssi)+[max_rssi]:continue
                if rssi < min_rssi:continue
                visitTimeList += vtlist.keys()
            if len(visitTimeList)==0:continue
            
            #visitTimeList = visitMsgs.keys()
            visitTimeList.sort()
            #print visitTimeList
            visittimes = len(visitTimeList)
            #visitTimeList
            st = visitTimeList[0]
            for i in range(visittimes):
                t1 = visitTimeList[i]
                if visittimes==1:
                    t2 = visitTimeList[i]
                elif i+1>=visittimes:
                    t2 = t1
                else:
                    t2 = visitTimeList[i+1]
                if visittimes!=1 and i+1<visittimes and t1==t2 :continue
                
                dur = self.get_dur(t1, t2)
                
                if dur>maxInterval or dur==0:
                    
                    et = t1
                    
                    cdur = self.get_dur(st, et)
                    #print mac,cdur,st,et
                    if cdur >=walkby and self.show=='walkby':
                        st = t2
                        continue
                    
                    if cdur <walkby and self.show=='customer':
                        st = t2
                        continue
                    
                    if cdur>=walkby:role=3
                    else:role=1
                    logging.debug("Identify Role   %s,%s,%s,type:%s,%s"%(mac,cdur,walkby,type(walkby),role))
                    if self.show not in ('rssi'):
                        
                        #msg = "mac: %s , role: %s , st: %s , et: %s , dur: %s"%(mac,3,st,et,round(cdur/float(60),2))
                        if   self.order == 'mac':
                            if mac not in macMsgs.keys():
                                macMsgs[mac] = []
                            macMsgs[mac] =macMsgs[mac]+ [{'st':st,'et':et,'dur':cdur,'role':role}]
                            #macMsgs.append( msg)
                        else:
                            hour = st.split(':')[0]
                            if hour not in hourMsgs.keys():
                                hourMsgs[hour] = []
                            hourMsgs[hour]  = hourMsgs[hour] +[{'mac':mac,'role':role,'st':st,'et':et,'dur':cdur}]
                    st = t2
        
        if self.order =='time':
            if self.type=='stat':
                
                return hourMsgs
            total = 0
            hours = hourMsgs.keys()
            hours.sort()
            for hour in hours:
                value = hourMsgs[hour]
                #print hour,len(value)
                total+=len(value)
            #logging.info('total customer freq %s'%total)

            hours = hourMsgs.keys()
            hours.sort()
            for hour in hours:
                msgs = hourMsgs[hour]
                
                if self.type == 'stat':
                    logging.debug( "hour:%s,visit count:%s"%(hour,len(msgs)))
                else:
                    if self.show in ('customer','walkby','all'):
                        for msg in msgs:
                            logging.debug( '%s:00:00-%s:00:00    %s'%(hour,int(hour)+1,msg))
                        

        elif self.order == 'mac':
            if self.type =='stat':
                return macMsgs
                
            else:
                total = 0
                for mac in macMsgs.keys():
                    #print mac
                    total+=len(macMsgs[mac])
                    for macValue in macMsgs[mac]:
                        pass
                        #print macValue
                        #logging.debug( mac)
                print total
        return macMsgs
                        
                        
    def filter_by_rssi(self,rawfile=None,device=None,devices=None,group='',mac=None,max=0,min=None):
        macsDict = {}
        try:
            rday = re.search('rawdata.([\d]{4}-[\d]{2}-[\d]{2}).',rawfile).group(1)
        except:
            logging.error('cont match day from rawfile %s '%(rawfile))
            return macsDict
        try:
            rawpath = re.search('^(.*?)/rawdata.[\d]{4}-[\d]{2}-[\d]{2}',rawfile).group(1)
        except:
            return macsDict
        raw_group_file = rawpath+'/rawdata_group/%s/%s.txt.tar.gz'%(rday,group)
        raw_dev_path = rawpath+'/rawdata_device/%s/'%rday
        raw_group_list= os.listdir(rawpath+'/rawdata_group/%s/'%(rday))
        if os.path.exists(raw_group_file):
            logging.debug('raw_group_file %s exists'%(raw_group_file))
            macsDict = self.filter_by_rssi_from_group_rawdata(rday=rday, raw_group_file=raw_group_file, group=group, mac=mac, max_rssi=max, min_rssi=min)

        elif os.path.exists(raw_dev_path):
            macsDict = self.filter_by_rssi_from_group_rawdata(rday=rday, raw_dev_path=raw_dev_path, group=group,devices=devices, mac=mac, max_rssi=max, min_rssi=min)

            

        elif len(raw_group_list)>0 and '%s.txt.tar.gz' not in raw_group_list:
            return macsDict
        else:
            macsDict = self.filter_by_dev_rssi(rawfile=rawfile, device=device, devices=devices, group=group, mac=mac, max=max, min=min)
        return macsDict
      
    def filter_by_rssi_from_group_rawdata(self,rday=None,raw_group_file=None,raw_dev_path=None,group=None,mac=None,max_rssi=0,min_rssi=None,devices=[]):
        logging.debug('raw_group_file start filter by rssi %s:%s'%(min_rssi,max_rssi))
        macsDict = {}
        if rday==None:
            try:
                rday = re.search('([\d]{4}-[\d]{2}-[\d]{2})',raw_group_file).group(1)
            except:
                logging.error('cont match day from raw_group_file %s '%(raw_group_file))
                return macsDict
            
            
        
        if raw_group_file!=None and os.path.exists(raw_group_file):
            msgs = self.openTarFile(raw_group_file)
        elif raw_dev_path!=None and len(devices)!=0:
            msgs = self.openDevTarFile(raw_dev_path, devices)
        
        else:
            return macsDict
        openingST,openingET = self.get_opening_time()
        employees = self.get_employees(group)
        for msg in msgs.split('\n'):
            msgLine = msg.split('.')
            if len(msgLine)!=6 and len(msgLine)!=5:
                if len(msgLine)!=0:
                    logging.warn('msg error %s'%(msg))
                continue
            if len(msgLine)==6:
                day,dev,dmac,dtime,rssi,rtime = msgLine
            elif len(msgLine)==5:
                day,dev,dmac,dtime,rssi = msgLine
            else:continue
            if len(dtime)!=8:
                logging.warning('dtime %s error.'%dtime)
                continue
            try:
                rssi = int(rssi)
            except Exception,error:
                logging.error("con not find rssi from msg %s"%(msg))
                continue
            if day!=rday:continue
            if dmac in employees:continue
            if mac!=None and dmac!=mac:continue
            if openingST and openingET:
                if dtime < openingST or dtime >= openingET:
                    continue
            
            if max_rssi!=None and min_rssi!=None:
                if int(rssi) in range(int(min_rssi),int(max_rssi))+[int(max_rssi)]:
                    if self.show=='rssi':
                        logging.debug( msg)
                    if dmac not in macsDict.keys():
                        macsDict[dmac]={}
                    if rssi not in macsDict[dmac].keys():
                        macsDict[dmac][rssi] = {}
                    #macsDict[dmac][rssi] = macsDict[dmac][rssi]+[dtime]
                    macsDict[dmac][rssi][dtime] = ''
                    #macsDict[dmac][dtime] = rssi
                else:
                    pass
        return macsDict
     
     
     
     
     
    def get_opening_time(self):
        if self.opening!=None:
            openingList = self.opening.split('.')
            if len(openingList)==2:
                openingST = self.opening.split('.')[0]
                openingET = self.opening.split('.')[1]
            else:
                openingST = '00:00:00'
                openingET = '23:59:59'
        else:
            openingST = '00:00:00'
            openingET = '23:59:59'
        return openingST,openingET
        
    def get_employees(self,group):
        try:
            
            employees = self.EMPLOYEES
            #employees = self.EMPLOYEES
            logging.info('group %s has employees %s'%(group,len(employees)))
        except:
            employees = []
            logging.error('group %s donot has employees'%(group))
        return employees

    def filter_by_dev_rssi(self,rawfile=None,device=None,devices=None,group='',mac=None,max=0,min=None):
        macsDict = {}
        try:
            rday = re.search('rawdata.([\d]{4}-[\d]{2}-[\d]{2}).',rawfile).group(1)
        except:
            logging.error('cont match day from rawfile %s '%(rawfile))
            return macsDict
        
        rawfile_tar = rawfile+'.tar.gz'
        if rawfile!=None and (os.path.exists(rawfile) or os.path.exists(rawfile_tar) ):
            #
            if os.path.exists(rawfile_tar):
                msgs = self.openTarFile(rawfile_tar)
            elif os.path.exists(rawfile):
                msgs = open(rawfile).read()
            else:msgs=''
        else:
            logging.error('rawfile %s not exists '%(rawfile))
            msgs = ''
        
        
        openingST,openingET = self.get_opening_time()
        employees = self.get_employees(group)
        for msg in msgs.split('\n'):
            #print msg
            msgLine = msg.split('.')
            #print len(msgLine)
            if len(msgLine)!=6 and len(msgLine)!=5:
                if len(msgLine)!=0:
                    logging.warn('msg error %s'%(msg))
                continue
            if len(msgLine)==6:
                day,dev,dmac,dtime,rssi,rtime = msgLine
            elif len(msgLine)==5:
                day,dev,dmac,dtime,rssi = msgLine
            else:continue
            if len(dtime)!=8:
                logging.warning('dtime %s error.'%dtime)
                continue
            try:
                rssi = int(rssi)
            except Exception,error:
                logging.error("con not find rssi from msg %s : %s "%(msg,error.message))
            if device!=None and dev!=device:continue
            if devices!=None and dev not in devices:
                #print devices
                continue
            if day!=rday:continue
            #print dmac
            if dmac in employees:
                #print dmac , 'is employee'
                continue
            if mac!=None and dmac!=mac:continue
            if openingST and openingET:
                if dtime < openingST or dtime >= openingET:
                    continue
            #print rssi
            if max!=None and min!=None:
#                 #print rssi
#                 #print 'xxxx',max,min
#                 if int(rssi) in range(int(min),int(max))+[int(max)]:
#                    
#                     if self.show=='rssi':
#                         logging.debug( msg)
#                     if dmac not in macsDict.keys():
#                         macsDict[dmac]={}
#                     macsDict[dmac][dtime] = rssi
#                 else:
#                     pass
#                     #print dev,mac,rssi
                if int(rssi) in range(int(min),int(max))+[int(min)]:
                    if self.show=='rssi':
                        logging.debug( msg)
                    if dmac not in macsDict.keys():
                        macsDict[dmac]={}
                    if rssi not in macsDict[dmac].keys():
                        macsDict[dmac][rssi] = {}
                    #macsDict[dmac][rssi] = macsDict[dmac][rssi]+[dtime]
                    macsDict[dmac][rssi][dtime] = ''
                    #macsDict[dmac][dtime] = rssi
                else:
                    pass
        #print len(macsDict)
        logging.info('get %s macs to del by rssi %s - %s'%(len(macsDict.keys()),min,max))
        return  macsDict
if __name__ == '__main__':


    sys.path.append('../')
    from base.zhimind_datas import myZhimindDatas
    import argparse,re
    parser = argparse.ArgumentParser(description='args')
    parser.add_argument('--rawfile',metavar="rawdata文件(必选)",required=True)
    parser.add_argument('--device',metavar="需要判定角色的device(必选)",required=True)
    #parser.add_argument('--device',metavar="需要判定角色的device(必选)",required=True)
    parser.add_argument('--group',metavar="需要判定角色的group(必选)",required=True)
    parser.add_argument('--mac', metavar='需要判定角色的mac(可选，默认值不限制)', default=None)
    parser.add_argument('--show',metavar='查看类型：rssi，customer，walkby,all,stat(可选，默认值all)',default='all')
    parser.add_argument('--max',metavar='rssi的选择区间：最大值(可选，默认值0，必须是数字)',default=0,type=int)
    parser.add_argument('--min',metavar='rssi的选择区间：最小值(可选，默认值-70,必须是数字)',default=-70,type=int)
    parser.add_argument('--maxInterval',metavar='角色鉴定的最大间隔时长(可选，单位秒，默认值1800，数字)',default=30*60,type=int)
    parser.add_argument('--walkby',metavar='路人鉴定时长(可选，单位秒，默认值120，数字)',default=2*60,type=int)
    parser.add_argument('--order',metavar='show 结果排序:mac,time(可选，默认值按mac排序)',default='mac')
    parser.add_argument('--rtype',metavar='rtype 结果:stat,detail(可选，默认值detail)',default='detail')
    parser.add_argument('--opening',metavar='营业时间 09:00:00.21:00:00 前闭后开',default='00:00:00.24:00:00')
    args = parser.parse_args()
    
    rawfile = args.rawfile
    device = args.device
    mac = args.mac
    show = args.show
    max = args.max
    min = args.min
    maxInterval = args.maxInterval
    walkby = args.walkby
    order = args.order
    rtype = args.rtype
    group = args.group
    opening = args.opening
    try:
        day = re.search('rawdata\.([^\.]+)\.txt',rawfile).group(1)
    except:day=datetime.date.today().strftime('%Y-%m-%d')
    
 
    myIdentifyRole = IdentifyRole(rawfile,show=show,order = order,type=rtype,opening=opening)

    
   
    
    myIdentifyRole.EMPLOYEES = myZhimindDatas.get_employees( group=group,day=day)
    macsDict= myIdentifyRole.filter_by_rssi(rawfile=rawfile, min=min,group=group)
    macMsgs = myIdentifyRole.identify_role_by_dur(macsDict,maxInterval=maxInterval,walkby=walkby)
    fr = open('../log/macs.txt','a+')
    for mac,macInfo in macMsgs.iteritems():
        print mac,macInfo
        fr.write(mac+'\n')
    fr.close()
    